package me.buick.util.snmp.core.dao.impl.snmp;

import java.util.ArrayList;
import java.util.List;

import me.buick.util.snmp.core.SupportedOS;
import me.buick.util.snmp.core.dao.SystemInfoDAO;
import me.buick.util.snmp.core.dao.impl.snmp.os.linux.entity.HrSystemInfo;
import me.buick.util.snmp.core.pojo.CpuDetailedInfoPojo;
import me.buick.util.snmp.core.pojo.CpuOverviewInfoPojo;
import me.buick.util.snmp.core.pojo.MemoryInfoPojo;
import me.buick.util.snmp.core.pojo.SystemInfoPojo;

import org.opengoss.snmphibernate.api.ISnmpSession;

/**
 * 
 * Version 1.0
 * 
 * @author buick
 *
 */

public class SNMPSystemInfoDAO implements SystemInfoDAO, IPollable{
	
	ISnmpSession session = null;
	SupportedOS  os	     = SupportedOS.Linux;
	
	List<CpuDetailedInfoPojo> cpuDetailedFinalResult;
	MemoryInfoPojo			  memInfoPojoFinalResult;
	CpuOverviewInfoPojo		  cpuOverviewFinalResult;
	SystemInfoPojo			  systemInfoFinnalResule;
	
	public SNMPSystemInfoDAO(SupportedOS os, ISnmpSession session){
		this.session = session;
		this.os		 = os;
	}
	
	public List<CpuDetailedInfoPojo> getCPUDetailed(){
		if(this.cpuDetailedFinalResult != null){
			return this.cpuDetailedFinalResult;
		}
		return extractCPUDetailedInfo();
	}

	private List<CpuDetailedInfoPojo> extractCPUDetailedInfo() {
		if(this.os == SupportedOS.Windows){
			List<me.buick.util.snmp.core.dao.impl.snmp.os.windows.entity.HrProcessorEntry> processorResultList = null;
			try {
				processorResultList = session.getTable(me.buick.util.snmp.core.dao.impl.snmp.os.windows.entity.HrProcessorEntry.class);
			} catch (Exception e) {
				e.printStackTrace();
			}
			List<CpuDetailedInfoPojo> cpuInfoList = new ArrayList<CpuDetailedInfoPojo>();
			for(me.buick.util.snmp.core.dao.impl.snmp.os.windows.entity.HrProcessorEntry p : processorResultList){
				CpuDetailedInfoPojo tempcp = new CpuDetailedInfoPojo();
				tempcp.setCpuID(p.getHrProcessorFrwID());
				tempcp.setCpuLoad(p.getHrProcessorLoad());
				cpuInfoList.add(tempcp);
			}
			return cpuInfoList;
		}else if(this.os == SupportedOS.Linux){
			List<me.buick.util.snmp.core.dao.impl.snmp.os.linux.entity.HrProcessorEntry> processorResultList = null;
			try {
				processorResultList = session.getTable(me.buick.util.snmp.core.dao.impl.snmp.os.linux.entity.HrProcessorEntry.class);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			List<CpuDetailedInfoPojo> cpuInfoList = new ArrayList<CpuDetailedInfoPojo>();
			for(me.buick.util.snmp.core.dao.impl.snmp.os.linux.entity.HrProcessorEntry p : processorResultList){
				CpuDetailedInfoPojo tempcp = new CpuDetailedInfoPojo();
				tempcp.setCpuID(p.getHrProcessorFrwID());
				tempcp.setCpuLoad(p.getHrProcessorLoad());
				cpuInfoList.add(tempcp);
			}
			return cpuInfoList;
		}else{
			return null;
		}
	}
	
	public MemoryInfoPojo getMemoryInfoPojo(){
		if(memInfoPojoFinalResult != null){
			return memInfoPojoFinalResult;
		}
		return extractMemInfo();
	}

	private MemoryInfoPojo extractMemInfo() {
		MemoryInfoPojo mp = new MemoryInfoPojo();
		if(this.os == SupportedOS.Windows){
			List<me.buick.util.snmp.core.dao.impl.snmp.os.windows.entity.HrDiskUsageEntry> diskUsageResultList = null;
			try {
				diskUsageResultList = session.getTable(me.buick.util.snmp.core.dao.impl.snmp.os.windows.entity.HrDiskUsageEntry.class);
			} catch (Exception e1) {
				e1.printStackTrace();
			}
			for(me.buick.util.snmp.core.dao.impl.snmp.os.windows.entity.HrDiskUsageEntry d : diskUsageResultList){
				if(d.getHrStorageType() != null && (d.getHrStorageType().equalsIgnoreCase("1.3.6.1.2.1.25.2.1.2"))){
					long memTotal  = d.getHrStorageSize();
					long memUsed   = d.getHrStorageUsed();
					long allocUnit = d.getHrAllocationUnits();
					mp.setMemSizesBytes(memTotal*allocUnit);
					mp.setMemUsageBytes(memUsed*allocUnit);
				}else{
				   continue;
				}
			}
			return mp;
		}else if(this.os == SupportedOS.Linux){
			List<me.buick.util.snmp.core.dao.impl.snmp.os.linux.entity.HrDiskUsageEntry> diskUsageResultList = null;
			try{
				diskUsageResultList = session.getTable(me.buick.util.snmp.core.dao.impl.snmp.os.linux.entity.HrDiskUsageEntry.class);
			}catch(Exception e){
				e.printStackTrace();
			}
			for(me.buick.util.snmp.core.dao.impl.snmp.os.linux.entity.HrDiskUsageEntry d : diskUsageResultList){
				if(d.getHrStorageDescr() != null && (d.getHrStorageDescr().equalsIgnoreCase("Physical memory"))){
					long memTotal  = d.getHrStorageSize();
					long memUsed   = d.getHrStorageUsed();
					long allocUnit = d.getHrAllocationUnits();
					mp.setMemSizesBytes(memTotal*allocUnit);
					mp.setMemUsageBytes(memUsed*allocUnit);
				}else if(d.getHrStorageDescr() != null && (d.getHrStorageDescr().equalsIgnoreCase("Real Memory"))){
					long memTotal  = d.getHrStorageSize();
					long memUsed   = d.getHrStorageUsed();
					long allocUnit = d.getHrAllocationUnits();
					mp.setMemSizesBytes(memTotal*allocUnit);
					mp.setMemUsageBytes(memUsed*allocUnit);
				}else{
				   continue;
				}
			}
			return mp;
		}else{
			return null;
		}
	}
	
	public CpuOverviewInfoPojo getCPUOverview(){
		if(cpuOverviewFinalResult != null){
			return cpuOverviewFinalResult;
		}
		return extractCPUOerviewInfo();
	}

	private CpuOverviewInfoPojo extractCPUOerviewInfo() {
		CpuOverviewInfoPojo cpuPojo = new CpuOverviewInfoPojo();
		List<CpuDetailedInfoPojo> cpuDetailedResult = this.getCPUDetailed();
		if(cpuDetailedResult != null && cpuDetailedResult.size() > 0){
			int cpuLoad = 0;
			for(CpuDetailedInfoPojo cinfo : cpuDetailedResult){
				cpuLoad += cinfo.getCpuLoad();
			}
			cpuPojo.setCpuLoad(cpuLoad/cpuDetailedResult.size());
		}
		return cpuPojo;
	}
	
	public SystemInfoPojo getSystemInfoPojo(){
		if(systemInfoFinnalResule != null){
			return systemInfoFinnalResule;
		}
		return extractSystemInfo();
	}

	private SystemInfoPojo extractSystemInfo() {
		SystemInfoPojo sysInfoPojo = new SystemInfoPojo();
		if(this.os == SupportedOS.Windows){
			try{
				me.buick.util.snmp.core.dao.impl.snmp.os.windows.entity.HrSystemInfo sysInfo = (me.buick.util.snmp.core.dao.impl.snmp.os.windows.entity.HrSystemInfo) session.get(me.buick.util.snmp.core.dao.impl.snmp.os.windows.entity.HrSystemInfo.class);
				sysInfoPojo.setSystemDate(sysInfo.getHrSystemDate());
				sysInfoPojo.setSystemInitialLoadDevice(sysInfo.getHrSystemInitialLoadDevice());
				sysInfoPojo.setSystemInitialLoadParameters(sysInfo.getHrSystemInitialLoadParameters());
				sysInfoPojo.setSystemMaxProcesses(sysInfo.getHrSystemMaxProcesses());
				sysInfoPojo.setSystemNumUsers(sysInfo.getHrSystemNumUsers());
				sysInfoPojo.setSystemPocesses(sysInfo.getHrSystemPocesses());
				sysInfoPojo.setSystemUpTime(sysInfo.getHrSystemUpTime());
				return sysInfoPojo;
			}catch (Exception e){
				e.printStackTrace();
				return null;
			}
		}else if(this.os == SupportedOS.Linux){
			try {
				HrSystemInfo sysInfo = (HrSystemInfo) session.get(HrSystemInfo.class);
				sysInfoPojo.setSystemDate(sysInfo.getHrSystemDate());
				sysInfoPojo.setSystemInitialLoadDevice(sysInfo.getHrSystemInitialLoadDevice());
				sysInfoPojo.setSystemInitialLoadParameters(sysInfo.getHrSystemInitialLoadParameters());
				sysInfoPojo.setSystemMaxProcesses(sysInfo.getHrSystemMaxProcesses());
				sysInfoPojo.setSystemNumUsers(sysInfo.getHrSystemNumUsers());
				sysInfoPojo.setSystemPocesses(sysInfo.getHrSystemPocesses());
				sysInfoPojo.setSystemUpTime(sysInfo.getHrSystemUpTime());
				return sysInfoPojo;
			} catch (Exception e) {
				e.printStackTrace();
				return null;
			}
		}else{
			return null;
		}
	}

	public void poll(long interval) {
		this.cpuDetailedFinalResult = this.extractCPUDetailedInfo();
		this.cpuOverviewFinalResult = this.extractCPUOerviewInfo();
		this.systemInfoFinnalResule = this.extractSystemInfo();
		this.memInfoPojoFinalResult = this.extractMemInfo();
	}
}
